# Location/services.py
from django.utils import timezone
from django.db import models
from .models import PointRule, PointTransaction, Event, CommunityPost, EventDiscussion


class PointService:
    """积分服务类"""
    @staticmethod
    def get_points_for_rule(rule_type):
        """根据规则类型获取积分数"""
        try:
            rule = PointRule.objects.get(rule_type=rule_type, is_active=True)
            print(f"找到积分规则: {rule_type} -> {rule.points}积分")
            return rule.points
        except PointRule.DoesNotExist:
            print(f"警告: 未找到积分规则: {rule_type}")
            return 0  # 这里返回0会导致问题！

    @staticmethod
    def check_daily_limit(user, source_type):
        """检查每日积分上限"""
        today = timezone.now().date()

        try:
            rule = PointRule.objects.get(rule_type=source_type, is_active=True)
            if rule.daily_limit == 0:  # 0表示无限制
                return True

            today_count = PointTransaction.objects.filter(
                user=user,
                source_type=source_type,
                created_at__date=today
            ).count()

            result = today_count < rule.daily_limit
            if not result:
                print(f"用户 {user.username} 的 {source_type} 积分已达到今日上限")
            return result
        except PointRule.DoesNotExist:
            return True

    @staticmethod
    def award_points(user, source_type, description, related_event=None, related_post=None):
        """奖励积分 - 从规则获取积分数"""
        points = PointService.get_points_for_rule(source_type)

        if points <= 0:
            return False, "该积分规则未启用或积分为0"

        # 检查每日限制
        if not PointService.check_daily_limit(user, source_type):
            return False, "今日积分已达到上限"

        # 调用用户的 add_points 方法
        return user.add_points(points, source_type, description, related_event, related_post)

    @staticmethod
    def handle_daily_login(user):
        """处理每日登录积分"""
        today = timezone.now().date()

        # 检查是否是连续登录
        if user.last_login_date:
            yesterday = today - timezone.timedelta(days=1)
            if user.last_login_date == yesterday:
                user.consecutive_login_days += 1
            elif user.last_login_date < yesterday:
                user.consecutive_login_days = 1
        else:
            user.consecutive_login_days = 1

        user.last_login_date = today

        # 奖励登录积分
        points = PointService.get_points_for_rule('daily_login')
        success, message = user.add_points(
            points,
            'daily_login',
            f'连续登录第{user.consecutive_login_days}天'
        )

        user.save()
        return success, message

    @staticmethod
    def handle_event_creation(user, event):
        """处理创建活动积分 - 详细调试版"""
        print(f"🔍 [积分调试] 开始处理活动创建积分")
        print(f"🔍 [积分调试] 用户: {user.username}, 活动: {event.title}")

        # 检查是否已经奖励过积分
        existing_transaction = PointTransaction.objects.filter(
            user=user,
            source_type='event_create',
            related_event=event,
            transaction_type='earn'
        ).exists()

        if existing_transaction:
            print(f"⚠️ [积分调试] 用户 {user.username} 已经获得过该活动的创建积分")
            return False, "已经获得过该活动的创建积分"

        print(f"✅ [积分调试] 准备奖励创建活动积分")
        points = PointService.get_points_for_rule('event_create')
        print(f"🔍 [积分调试] 获取到的积分点数: {points}")

        if points <= 0:
            print(f"❌ [积分调试] 积分规则返回0或负数点数: {points}")
            return False, "该积分规则未启用或积分为0"

        # 检查每日限制
        if not PointService.check_daily_limit(user, 'event_create'):
            return False, "今日创建活动积分已达到上限"

        print(f"🔍 [积分调试] 调用用户 add_points 方法")
        result = user.add_points(
            points,
            'event_create',
            f'创建活动: {event.title}',
            related_event=event
        )
        print(f"🔍 [积分调试] add_points 返回结果: {result}")
        return result

    @staticmethod
    def debug_point_system():
        """诊断积分系统状态"""
        from .models import PointRule

        print("=== 积分系统诊断 ===")

        # 检查所有积分规则
        rules = PointRule.objects.all()
        print(f"积分规则数量: {rules.count()}")

        for rule in rules:
            print(f"规则: {rule.rule_type} - {rule.points}分 - 启用: {rule.is_active} - 每日限制: {rule.daily_limit}")

        # 检查event_create规则
        try:
            event_rule = PointRule.objects.get(rule_type='event_create')
            print(f"✅ event_create规则: {event_rule.points}分, 启用: {event_rule.is_active}")
        except PointRule.DoesNotExist:
            print(f"❌ event_create规则不存在!")

        print("=== 诊断结束 ===")

    # 在 handle_event_status_change 开始处调用诊断
    @staticmethod
    def handle_event_status_change(event, old_status, new_status):
        """处理活动状态变化的积分奖励和撤销"""
        # 先运行诊断
        PointService.debug_point_system()

        print(f"🔍 [状态变化处理] 活动: {event.title}, 状态变化: {old_status} -> {new_status}")

        # 当活动从 pending 变为 published 时奖励积分
        if old_status == 'pending' and new_status == 'published':
            print(f"✅ [状态变化处理] 活动审核通过，奖励组织者积分")
            result = PointService.handle_event_creation(event.organizer, event)
            print(f"🔍 [状态变化处理] 积分奖励结果: {result}")
            return result

        # 当活动从 pending 变为 rejected 时撤销积分
        elif old_status == 'pending' and new_status == 'rejected':
            print(f"❌ [状态变化处理] 活动被拒绝，撤销已发放的积分")
            return PointService.revoke_event_creation_points(event.organizer, event)

        print(f"🔍 [状态变化处理] 状态变化不触发积分操作: {old_status} -> {new_status}")
        return False, "状态变化不触发积分操作"

    @staticmethod
    def revoke_event_creation_points(user, event):
        """撤销创建活动的积分"""
        try:
            # 查找相关的积分记录
            transaction = PointTransaction.objects.filter(
                user=user,
                source_type='event_create',
                related_event=event,
                transaction_type='earn'
            ).first()

            if transaction:
                # 撤销积分（扣除积分并创建撤销记录）
                points_to_revoke = transaction.points

                # 创建撤销记录
                PointTransaction.objects.create(
                    user=user,
                    transaction_type='spend',
                    points=points_to_revoke,
                    source_type='event_create',
                    description=f'活动审核拒绝撤销: {event.title}',
                    related_event=event
                )

                # 更新用户积分
                user.points = max(0, user.points - points_to_revoke)
                user.save()

                print(f"✅ 已撤销 {points_to_revoke} 积分")
                return True, f"已撤销 {points_to_revoke} 积分"
            else:
                print("⚠️ 未找到对应的积分记录")
                return False, "未找到积分记录"

        except Exception as e:
            print(f"❌ 撤销积分失败: {str(e)}")
            return False, f"撤销积分失败: {str(e)}"

    @staticmethod
    def handle_event_participation(user, event):
        """处理参加活动积分"""
        return PointService.award_points(
            user,
            'event_join',
            f'参加活动: {event.title}',
            related_event=event
        )

    @staticmethod
    def handle_event_review(user, event, review):
        """处理活动评价积分"""
        return PointService.award_points(
            user,
            'event_review',
            f'评价活动: {event.title}',
            related_event=event
        )

    @staticmethod
    def handle_post_creation(user, post):
        """处理发布帖子积分"""
        return PointService.award_points(
            user,
            'post_create',
            f'发布帖子: {post.title}',
            related_post=post
        )

    @staticmethod
    def handle_comment_creation(user, comment, is_discussion=False):
        """处理发表评论积分"""
        if is_discussion:
            # 活动讨论评论
            return PointService.award_points(
                user,
                'comment_create',
                f'评论活动: {comment.event.title}',
                related_event=comment.event
            )
        else:
            # 社区帖子评论
            return PointService.award_points(
                user,
                'comment_create',
                f'评论帖子: {comment.post.title}',
                related_post=comment.post
            )

    @staticmethod
    def handle_profile_completion(user):
        """处理完善资料积分"""
        points = PointService.get_points_for_rule('profile_complete')
        return user.add_points(
            points,
            'profile_complete',
            '完善个人资料'
        )

    @staticmethod
    def get_user_points_summary(user):
        """获取用户积分概览"""
        today = timezone.now().date()

        # 今日获得积分
        today_points = PointTransaction.objects.filter(
            user=user,
            transaction_type='earn',
            created_at__date=today
        ).aggregate(total=models.Sum('points'))['total'] or 0

        # 本月获得积分
        month_start = today.replace(day=1)
        month_points = PointTransaction.objects.filter(
            user=user,
            transaction_type='earn',
            created_at__date__gte=month_start
        ).aggregate(total=models.Sum('points'))['total'] or 0

        # 总获得积分
        total_earned = PointTransaction.objects.filter(
            user=user,
            transaction_type='earn'
        ).aggregate(total=models.Sum('points'))['total'] or 0

        # 总消费积分
        total_spent = PointTransaction.objects.filter(
            user=user,
            transaction_type='spend'
        ).aggregate(total=models.Sum('points'))['total'] or 0

        return {
            'total_points': user.points,
            'total_earned': total_earned,
            'total_spent': total_spent,
            'today_points': today_points,
            'month_points': month_points,
            'level': user.level,
            'experience': user.experience,
            'next_level_exp': (user.level + 1) * 1000,
            'progress_percentage': min(100, (user.experience / ((user.level + 1) * 1000)) * 100) if (
                                                                                                                user.level + 1) * 1000 > 0 else 0
        }

    #积分签到
    @staticmethod
    def handle_event_checkin(user, event):
        """处理活动签到积分奖励"""
        print(f"🔍 [签到积分调试] 开始处理活动签到积分")
        print(f"🔍 [签到积分调试] 用户: {user.username}, 活动: {event.title}")

        # 检查是否已经奖励过签到积分
        existing_transaction = PointTransaction.objects.filter(
            user=user,
            source_type='event_checkin',
            related_event=event,
            transaction_type='earn'
        ).exists()

        if existing_transaction:
            print(f"⚠️ [签到积分调试] 用户 {user.username} 已经获得过该活动的签到积分")
            return False, "已经获得过该活动的签到积分"

        print(f"✅ [签到积分调试] 准备奖励签到积分")
        points = PointService.get_points_for_rule('event_checkin')
        print(f"🔍 [签到积分调试] 获取到的积分点数: {points}")

        if points <= 0:
            print(f"❌ [签到积分调试] 签到积分规则返回0或负数点数: {points}")
            return False, "签到积分规则未启用或积分为0"

        # 检查每日限制
        if not PointService.check_daily_limit(user, 'event_checkin'):
            return False, "今日签到积分已达到上限"

        print(f"🔍 [签到积分调试] 调用用户 add_points 方法")
        result = user.add_points(
            points,
            'event_checkin',
            f'活动签到: {event.title}',
            related_event=event
        )
        print(f"🔍 [签到积分调试] add_points 返回结果: {result}")
        return result

